package com.zhou.framework.util;

import com.zhou.framework.constant.CacheKeyEnum;
import com.zhou.framework.redis.util.RedisUtil;
import com.zhou.org.dao.Enum;
import com.zhou.org.service.EnumService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lang.zhou
 * @since 2023/2/6 10:31
 */
@Slf4j
@Component
public class EnumUtil implements ApplicationRunner {

    @Autowired
    private EnumService enumService;
    @Autowired
    private RedisUtil redisUtil;
    private static final Integer LOCK = 1;


    private String getCacheKey(String key){

        return CacheKeyEnum.ENUM + key;
    }

    public void load(){
        synchronized (LOCK){
            redisUtil.del(CacheKeyEnum.ENUM);

            List<Enum> list = enumService.list();
            Map<String, Map<String, Enum>> collect = list.stream().collect(Collectors.groupingBy(Enum::getEnumType,
                    Collectors.toMap(Enum::getEnumKey, o -> o, (v1, v2) -> v1)));
            for (Map.Entry<String, Map<String, Enum>> entry : collect.entrySet()) {
                redisUtil.setHash(getCacheKey(entry.getKey()),entry.getValue());
            }
        }
    }

    public void load(String type){
        Map<String, Enum> collect = enumService.getByType(type).stream().collect(Collectors.toMap(Enum::getEnumKey, o -> o, (v1, v2) -> v1));
        redisUtil.setHash(getCacheKey(type),collect);
    }

    public void set(Enum data){
        redisUtil.setHash(getCacheKey(data.getEnumType()),data.getEnumKey(),data);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        this.load();
        log.info("缓存枚举成功");
    }

    public Enum getEnumByTypeAndKey(String type, String key){
        return redisUtil.getHash(type, key);
    }

    public Map<String, Enum> getEnumMapByType(String type){
        return redisUtil.getHashMap(type);
    }

    public List<Enum> getEnumListByType(String type){
        Map<String, Enum> map = getEnumMapByType(type);
        List<Enum> list = new ArrayList<>(map.size());
        list.addAll(map.values());
        list.sort(Comparator.comparing(Enum::getSort));
        return list;
    }
}
